﻿namespace HuwmanCode

open System
open HuwmanCode
open NUnit.Framework
open FsUnit

[<TestFixture>]
type ``Func ``() =
    [<Test>]
    member this.``Func.Try - func invokes``() =
        let func = new Func<_>(fun _ -> true)
        let compensate = new Action<Exception>(fun e -> ())
        let result = func |> Func.Try(compensate)

        result |> Option.isSome |> should be True
        result |> Option.get |> should be True

    [<Test>]
    member this.``Func.Try - compensation invokes when func raises exn``() =
        let compensationInvokes = ref false
        let func = new Func<_>(fun _ -> failwith "A big bugger up!")
        let compensate = new Action<Exception>(fun e -> compensationInvokes := true)
        func |> Func.Try(compensate) |> ignore

        !compensationInvokes |> should be True

    [<Test>]
    member this.``Func.Try - returns None when func raises exn``() =
        let func = new Func<_>(fun _ -> failwith "A big bugger up!")
        let compensate = new Action<Exception>(fun e -> ())

        func |> Func.Try(compensate) |> Option.isNone |> should be True

    [<Test>]
    member this.``Func.TryWithRethrow - func invokes``() =
        let func = new Func<_>(fun _ -> true)
        let compensate = new Action<Exception>(fun e -> ())
        let result = func |> Func.TryWithRethrow(compensate)

        result |> should be True

    [<Test>]
    member this.``Func.TryWithRethrow - compensation invokes when func raises exn``() =
        let compensationInvokes = ref false
        let func = new Func<_>(fun _ -> failwith "A big bugger up!")
        let compensate = new Action<Exception>(fun e -> compensationInvokes := true)
        
        try
            func |> Func.TryWithRethrow(compensate) |> ignore
        with _ -> ()

        !compensationInvokes |> should be True

    [<Test>]
    member this.``Func.TryWithRethrow - exn is reraised when func raises exn``() =
        let exceptionIsReraised = ref false
        let func = new Func<_>(fun _ -> failwith "A big bugger up!")
        let compensate = new Action<Exception>(fun e -> ())
        
        try
            func |> Func.TryWithRethrow(compensate) |> ignore
        with _ -> exceptionIsReraised := true

        !exceptionIsReraised |> should be True